package com.sangeng.controller;

import com.sangeng.domain.ResponseResult;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    /**
     * 这里讲一下 @PreAuthorize的hasAuthority方法流程 (当前写法不会加入前缀)
     *
     * 1. 获取当前用户权限列表,  是从 SecurityContextHolder.getContext().getAuthentication().getAuthorities()中获取到的,也就是Security的上下文,
     *       而这个SecurityContextHolder.getContext().getAuthentication().getAuthorities()方法中存储的权限列表是 LoginUser 调用 getAuthorities 获取到的
     *      具体存放时间是在我们自定义的过滤器中用户认证成功之后,将用户权限列表存放到SecurityContextHolder中.(具体 去看代码) <--  SecurityContextHolder.getContext().getAuthentication().getAuthorities()方法
     *      而LoginUser 调用 getAuthorities 中的权限字段是在 UserDetailsServiceImpl 中,我们查询用户信息后封装进 LoginUser时写进getAuthorities方法的
     *
     * 2.判断 资源 权限是否需要加入前缀,如果需要则加入前缀,如:前缀为ROLE,则返回前缀+权限字段(ROLE_system:dept:test)作为 资源权限 到第三步,
     * 如果不需要则返回权限字段(system:dept:test)作为资源权限,也就是不做处理直接去第 3 步
     *
     * 3. 遍历用户权限列表, 判断当前资源权限是否在用户权限列表中 ,这一步会把 第1步 获取的用户权限列表进行遍历,并对比 第2步 传入的资源权限字段是否一致,
     *      如果一致则返回true,否则返回false
     *
     */

    @RequestMapping("/hello")
    @PreAuthorize("hasAuthority('system:dept:test')")//hasAuthority('system:dept:test')返回boolean类型,true就会继续执行方法,false则返回403
                                                    // (具体错误返回查看Security异常处理类中认证错误的异常配置) Forbidden
    public String hello(){
        return "hello";
    }

    @RequestMapping("/testCors")
    @PreAuthorize("@ex.hasAuthority('system:dept:test')")
    //在SPEL表达式中使用 @ex相当于获取容器中bean的名字未ex的对象。然后再调用这个对象的hasAuthority方法

    //@PreAuthorize("hasAuthority('test')")//要求登录用户拥有test权限才可以访问
    public ResponseResult testCors(){
        return new ResponseResult(200,"testCors");
    }
}
